﻿package Framework.Protocol.CDFProtocol
{
    import Framework.Protocol.IProtocol;
    import Framework.Util.*;
    
    import flash.utils.*;

    public class Protocol extends Object implements IProtocol
    {
        private var _bytesBuffer:ByteArray;
        private var _readHead:Boolean;
        private var _protocolHead:ProtocolHead;

        public function Protocol()
        {
            this._readHead = false;
            this._protocolHead = new ProtocolHead();
            this._bytesBuffer = new ByteArray();
            this._bytesBuffer.endian = Endian.LITTLE_ENDIAN;
        }

        public function handleData(bytes:ByteArray, businesshandler:IBusinessHandler, iohandler:IIOHandler, ibusinesshandler:IBusinessHandler) : int
        {
            var ibytes:ByteArray = null;
            var iibytes:ByteArray = null;
            this._bytesBuffer.position = this._bytesBuffer.length;
            this._bytesBuffer.writeBytes(bytes, 0, bytes.length);
            this._bytesBuffer.position = 0;
            while (true)
            {
                
                if (this._readHead)
                {
                    if (this._bytesBuffer.length - this._bytesBuffer.position >= this._protocolHead.messageSize)
                    {
                        ibytes = new ByteArray();
                        ibytes.endian = Endian.LITTLE_ENDIAN;
                        this._bytesBuffer.readBytes(ibytes, 0, this._protocolHead.messageSize);
                        this._readHead = false;
                        if (this._protocolHead.compressionStatus == 1)
                        {
                            ibytes.uncompress();
                        }
                        if (!businesshandler.handlePacket(ibytes, ibusinesshandler))
                        {
                            return -1;
                        }
                    }
                    else
                    {
                        break;
                    }
                    continue;
                }
                if (this._bytesBuffer.length - this._bytesBuffer.position < ProtocolHead.CDF_PROTOCOL_HEAD_SIZE)
                {
                    break;
                }
                this._protocolHead.__read(this._bytesBuffer);
                this._readHead = true;
                if (this._protocolHead.messageSize > ProtocolHead.CDF_PROTOCOL_MAX_SIZE || this._protocolHead.messageSize < 0)
                {
                    return -1;
                }
            }
            if (this._bytesBuffer.position != 0)
            {
                iibytes = new ByteArray();
                iibytes.writeBytes(this._bytesBuffer, this._bytesBuffer.position);
                this._bytesBuffer = iibytes;
                this._bytesBuffer.endian = Endian.LITTLE_ENDIAN;
            }
            return bytes.length;
        }

        public function sendDataEncrypt(bytes:ByteArray, iohandler:IIOHandler) : Boolean
        {
            if (bytes.length > ProtocolHead.CDF_PROTOCOL_MAX_SIZE)
            {
                return false;
            }
            var byte:* = new ByteArray();
            byte.endian = Endian.LITTLE_ENDIAN;
            var head:ProtocolHead = new ProtocolHead();
            new ProtocolHead().messageSize = bytes.length;
            head.__write(byte);
            byte.writeBytes(bytes, 0, bytes.length);
            return iohandler.sendData(byte) != -1;
        }

        public function clear() : void
        {
            this._bytesBuffer.clear();
            this._readHead = false;
        }
    }
}
